import logging
import re
import os
import subprocess
import sys
import urlparse

from oriolus.trotter.core import Fetcher, FetchError

class WgetFetcher(Fetcher):
    """
    Fetcher that uses wget utility.
    """
    
    __FTP_PREFIX = "ftp"
    __HTTP_PREFIX = "http"
    __VERSION_PATTERN = "GNU Wget (\d+\.\d+\.\d+)"
    __TRUE_DATA_PATTERN = "^\d{4}\-\d{2}\-\d{2}\s{1}\d{2}\:\d{2}\:\d{2}\s{1}URL\:.*\"(?!.*\.listing\")(.+)\"\s{1}\[(\d+)\]$"
    
    def __init__(self, cache, timeout = 30):
        Fetcher.__init__(self, cache)
        self.__timeout = timeout
        self.__base_command = ["wget", "--timeout=%s" % timeout, "--no-verbose", "--tries=3", "--directory-prefix=%s" % cache, "--no-directories", "--continue"]
        self.logger = logging.getLogger("WgetFetcher")
        self.logger.debug("init fetcher: cache - '%s', timeout = %d", self.cache, timeout)
        
        try:
            p = subprocess.Popen(["wget", "--version", "-nv"], stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, universal_newlines = True)
            (std_out, std_err) = p.communicate()
            
            if len(std_err) > 0:
                raise FetchError(std_err)
                
            result = re.search(self.__VERSION_PATTERN, std_out)
            if result:
                self.logger.info("Wget version is %s", result.group(1))
            else:
                self.logger.warn("Wget version is unrecognized.")
        except:
            message = "Unable to initialize wget executable"
            self.__logerror__(self.logger, message)
            raise FetchError(message)
    
    def get(self, url, login = None, password = None):
        self.logger.info("Open URL '%s'." % url)
        args = [url] 
        if login and password:
            if urlparse.urlparse(url)[0] == __FTP_PREFIX:
                args = args + ["--ftp-user=%s" % login, "--ftp-password=%s" % password]
            elif urlparse.urlparse(url)[0] == __HTTP_PREFIX:
                args = args + ["--http-user=%s" % login, "--http-password=%s" % password]
            
        p = subprocess.Popen(self.__base_command + args, stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, universal_newlines = True)
        (std_out, std_err) = p.communicate()
        
        self.logger.debug("Data readed: std_out: %s", std_out)
        self.logger.debug("Data readed: std_err: %s", std_err)

        if len(std_err) > 0:
            result = re.compile(self.__TRUE_DATA_PATTERN, re.M).search(std_err)
            if result:
                self.logger.info("File '%s' saved." % result.group(1))
                return result.group(1)
            else:
                raise FetchError(std_err)
        else:
            raise FetchError("Unable to get file. Unknown output.")